# -*- coding: utf-8 -*-
import tkinter as tk
from data_account import StockAccount
import logging, log

# ui logger
logger_ui = logging.getLogger('Master.AppUI')


class AppUI(object):
    def __init__(self, app_name, app_size):
        # window
        self.win = tk.Tk()

        self.win.title(app_name)
        self.win.geometry(app_size)

    def run(self):
        # Config interface and run mainloop
        self.app_main_frame = MainInterface(self.win, side='top', fill='both', expand=True)
        self.win.mainloop()


class MainInterface(object):
    def __init__(self, master, side, fill='both', expand=True):
        # lable setting
        label_width = 5

        # fram of main interface
        self.frame = tk.Frame(master)
        self.frame.pack(side=side, fill=fill, expand=expand)

        # fram of money
        self.money_frame = tk.Frame(self.frame)
        self.money_frame.pack(side='top', fill='both', expand=True, padx=1, pady=1)

        # lable - money
        self.money_label = tk.Label(self.money_frame, text='Start money', width=label_width)
        self.money_label.pack(side='left', fill='both', expand=True, padx=1, pady=1)

        # entrys - money
        self.money_entry_str = tk.StringVar()
        self.money_entry = tk.Entry(self.money_frame,
                                    textvariable=self.money_entry_str)
        self.money_entry.pack(side='left', fill='both', expand=True, padx=1, pady=1)

        # fram of number
        self.number_frame = tk.Frame(self.frame)
        self.number_frame.pack(side='top', fill='both', expand=True, padx=1, pady=1)

        # lable - number
        self.number_label = tk.Label(self.number_frame, text='Numbers', width=label_width)
        self.number_label.pack(side='left', fill='both', expand=True, padx=1, pady=1)

        # entrys - number
        self.number_entry_str = tk.StringVar()
        self.number_entry = tk.Entry(self.number_frame,
                                     textvariable=self.number_entry_str)
        self.number_entry.pack(side='right', fill='both', expand=True, padx=1, pady=1)

        # fram of price
        self.price_frame = tk.Frame(self.frame)
        self.price_frame.pack(side='top', fill='both', expand=True, padx=1, pady=1)

        # lable - price
        self.price_label = tk.Label(self.price_frame, text='Price', width=label_width)
        self.price_label.pack(side='left', fill='both', expand=True, padx=1, pady=1)

        # entrys - price
        self.price_entry_str = tk.StringVar()
        self.price_entry = tk.Entry(self.price_frame,
                                    textvariable=self.price_entry_str)
        self.price_entry.pack(side='right', fill='both', expand=True, padx=1, pady=1)

        # fram of button
        self.btn_frame = tk.Frame(self.frame)
        self.btn_frame.pack(side='top', fill='both', expand=True, padx=1, pady=1)

        # buttons
        self.btn_start = tk.Button(self.btn_frame, text='初始', relief='groove',
                                   command=self.start)
        self.btn_start.pack(side='left', fill='both', expand=True, padx=1, pady=1)

        # buttons
        self.btn_reset = tk.Button(self.btn_frame, text='重置', relief='groove',
                                   command=self.reset)
        self.btn_reset.pack(side='left', fill='both', expand=True, padx=1, pady=1)

        # buttons
        self.btn_manual_buy = tk.Button(self.btn_frame, text='手动买', relief='groove',
                                        command=self.buy_calculation)
        self.btn_manual_buy.pack(side='left', fill='both', expand=True, padx=1, pady=1)

        # buttons
        self.btn_manual_sell = tk.Button(self.btn_frame, text='手动卖', relief='groove',
                                         command=self.sell_calculation)
        self.btn_manual_sell.pack(side='left', fill='both', expand=True, padx=1, pady=1)

        # buttons
        self.btn_intelli_buy = tk.Button(self.btn_frame, text='智能买', relief='groove',
                                         command=self.buy_intelligent_calculation)
        self.btn_intelli_buy.pack(side='left', fill='both', expand=True, padx=1, pady=1)

        # buttons
        self.btn_intelli_sell = tk.Button(self.btn_frame, text='智能卖', relief='groove',
                                          command=self.sell_intelligent_calculation)
        self.btn_intelli_sell.pack(side='left', fill='both', expand=True, padx=1, pady=1)

        # fram of button
        self.btn_auo_frame = tk.Frame(self.frame)
        self.btn_auo_frame.pack(side='top', fill='both', expand=True, padx=1, pady=1)

        # buttons
        self.btn_auto_downtrend = tk.Button(self.btn_auo_frame, text='下趋全自动', relief='groove',
                                            command=self.buy_intelligent_downtrend)
        self.btn_auto_downtrend.pack(side='left', fill='both', expand=True, padx=1, pady=1)

        # buttons
        self.btn_auto_uptrend = tk.Button(self.btn_auo_frame, text='上趋全自动', relief='groove',
                                          command=self.buy_intelligent_uptrend)
        self.btn_auto_uptrend.pack(side='left', fill='both', expand=True, padx=1, pady=1)

        # buttons
        self.btn_auto_fixed = tk.Button(self.btn_auo_frame, text='定投', relief='groove',
                                        command=self.buy_intelligent_fixed)
        self.btn_auto_fixed.pack(side='left', fill='both', expand=True, padx=1, pady=1)

    def start(self):
        """
        Start to init the stock account
        :return: None
        """
        # init
        money = float(self.money_entry_str.get())
        self.stock_account = StockAccount(money)

        # print
        self._print_start_data()

    def reset(self):
        """
        Reset data
        :return: None
        """
        # reset
        money = float(self.money_entry_str.get())
        self.stock_account.reset_account(money)

        # print
        self._print_start_data()

    def buy_calculation(self):
        """
        Calculate the buy operation
        :return: None
        """
        # caluration
        number_in = float(self.number_entry_str.get())
        price_in = float(self.price_entry_str.get())
        self.stock_account.buy(number_in, price_in)

        # print
        self._print_cur_data('Buy', number_in, price_in)

    def sell_calculation(self):
        """
        Calculate the sell operation
        :return: None
        """
        # caluration
        number_out = float(self.number_entry_str.get())
        price_out = float(self.price_entry_str.get())
        self.stock_account.sell(number_out, price_out)

        # print
        self._print_cur_data('Sell', number_out, price_out)

    def buy_intelligent_calculation(self):
        """
        Intelligent calculation buy
        :return: None
        """
        price_in = float(self.price_entry_str.get())
        number_in = self.stock_account.intelligent_buy(price_in)

        # print
        self._print_cur_data('Buy', number_in, price_in)

    def sell_intelligent_calculation(self):
        """
        Intelligent calculation sell
        :return: None
        """
        price_out = float(self.price_entry_str.get())
        number_out = self.stock_account.intelligent_sell(price_out)

        # print
        self._print_cur_data('Sell', number_out, price_out)

    def buy_intelligent_downtrend(self):
        """
        In the downtrend, a set of price would be buy and sell based on the strategy
        :return:
        """
        self._calculate('downtrend')

    def buy_intelligent_uptrend(self):
        """
        In the uptrend, a set of price would be buy and sell based on the strategy
        :return:
        """
        self._calculate('uptrend')

    def buy_intelligent_fixed(self):
        """
        Buy in fixed fee
        :return:
        """
        self._calculate('fixed')

    def _calculate(self, flag):
        # get widget data
        base_number = float(self.number_entry_str.get())
        price_str_list = self.price_entry_str.get()

        # cal
        if flag == 'downtrend':
            self.stock_account.intelligent_auto_downtrend(base_number, price_str_list)
        elif flag == 'uptrend':
            self.stock_account.intelligent_auto_uptrend(base_number, price_str_list)
        elif flag == 'fixed':
            self.stock_account.intelligent_auto_fixed(base_number, price_str_list)
        else:
            logger_ui.error('calculate flag error.')

        # print
        trend_dict = self.stock_account.get_trend_data_dict
        price_list = trend_dict['price_list']
        average_list = trend_dict['average_list']
        profit_list = trend_dict['profit_list']
        stock_list = trend_dict['stock_list']
        realtime_money_list = trend_dict['realtime_money_list']
        for i in range(len(price_list)):
            self._print_trend_data(price_list[i], average_list[i], profit_list[i], stock_list[i],
                                   realtime_money_list[i])

    def _print_start_data(self):
        logger_ui.info('---------------sep----------------')
        logger_ui.info('Start money {0}, stock {1}'.
                       format(self.stock_account.get_start_money, self.stock_account.get_stock))

    def _print_trend_data(self, price, average, profit, stock, realtime_money):
        logger_ui.info('---------------sep----------------')
        logger_ui.info('Price {0}, Average {1}, Current profit {2}, Stock {3}, Realtime money {4}'.
                       format(price, average, profit, stock, realtime_money))

    def _print_cur_data(self, operation, number, price):
        """
        Print the current account data
        :param operation: buy or sell
        :param number: number in or out
        :param price: price in or out
        :return: None
        """
        logger_ui.info('---------------sep----------------')
        logger_ui.info('{} operation:'.format(operation))
        logger_ui.info('Buy {0} number with {1} price'.format(number, price))
        logger_ui.info('Current realtime money {0}, stock {1}'.
                       format(self.stock_account.get_realtime_money, self.stock_account.get_stock))
        logger_ui.info('Current number {0}, average {1}, tax {2}'.
                       format(self.stock_account.get_number, self.stock_account.get_average,
                              self.stock_account.get_tax))
        logger_ui.info('Current profit {}, profit percent {:.2f}%, stock percent {:.2f}%'.
                       format(self.stock_account.get_profit, self.stock_account.get_profit_percent,
                              self.stock_account.get_invest_percent))
